package socket.myRPC.rpc.transport;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import socket.myRPC.rpc.Dispatcher;
import socket.myRPC.rpc.protocol.MyContent;
import socket.myRPC.rpc.protocol.MyHeader;
import socket.myRPC.util.Define;
import socket.myRPC.util.PackageMsg;
import socket.myRPC.util.SerDerUtil;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

class ChannelHandlerRunnable implements Runnable {
  
  PackageMsg packageMsg;
  ChannelHandlerContext ctx;
  
  public ChannelHandlerRunnable(ChannelHandlerContext ctx, PackageMsg packageMsg) {
    this.ctx = ctx;
    this.packageMsg = packageMsg;
  }
  
  @Override
  public void run() {
    // 这里是 服务名称 以及 类名称
    String serviceName = packageMsg.getContent().getName();
    // 这里 是 方法名称
    String methodName = packageMsg.getContent().getMethodName();
    
    Object oClass = Dispatcher.get(serviceName);
    Class<?> clazz = oClass.getClass();
    
    Object res;
    try {
      // 拿到 Method
      Method method = clazz.getMethod(methodName, packageMsg.getContent().getParameterTypes());
      // 执行方法, 传递参数
      // res 这里是 拿到 执行返回值
      res = method.invoke(oClass, packageMsg.getContent().getArgs());
    } catch (NoSuchMethodException | InvocationTargetException |
             IllegalAccessException e) {
      throw new RuntimeException(e);
    }
    
    // 构建 content
    MyContent content = new MyContent();
    content.setRes(res);
    byte[] contentByte = SerDerUtil.serialize(content);
    
    // 构建 header
    MyHeader header = new MyHeader();
    // 将 request的RequestID 赋值给 response
    header.setRequestID(packageMsg.getHeader().getRequestID());
    header.setFlag(Define.RESPONSE_FLAG);
    header.setDataLen(contentByte.length);
    byte[] headerByte = SerDerUtil.serialize(header);
    
    // 这里构建 直接内存
    ByteBuf byteBuf = PooledByteBufAllocator.DEFAULT.directBuffer(headerByte.length + contentByte.length);
    byteBuf.writeBytes(headerByte);
    byteBuf.writeBytes(contentByte);
    ctx.writeAndFlush(byteBuf);
  }
}

/**
 * 服务 请求事件
 *
 * @author lihh
 */
public class ServerRequestHandler extends ChannelInboundHandlerAdapter {
  @Override
  public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    PackageMsg packageMsg = (PackageMsg) msg;
    
    // 业务级别 使用一个单独的线程来执行
    /*
     这里 尝试将 thread io 以及 业务进行分离
     * */
    ctx.executor().execute(new ChannelHandlerRunnable(ctx, packageMsg));
  }
}
